<template>
  <section class="relative">
    <div
      @mousedown="handleMouseDownBox"
      :style="parentStyle"
      class="hover:cursor-move absolute h-[200px] w-[200px] bg-[pink]"
    >
      <div
        :class="`shape-point ${point}`"
        v-for="(point, index) in select ? pointList : []"
        :style="usePointStyle(point, index, item.attr, cursorResize)"
        @mousedown="useMousePointHandle($event, point, item.attr)"
      ></div>
    </div>
  </section>
</template>

<script setup lang="ts">
import { throttle, cloneDeep } from 'lodash';

import { reactive, ref } from 'vue';
const select = ref(true);
const cursorResize = ['n', 'e', 's', 'w', 'nw', 'ne', 'sw', 'se'];
const item = reactive({
  attr: {
    x: 0,
    y: 0,
    w: 200,
    h: 200,
  },
});

const parentStyle = computed(() => {
  return {
    width: `${item.attr.w}px`,
    height: `${item.attr.h}px`,
    top: `${item.attr.y}px`,
    left: `${item.attr.x}px`,
  };
});

const pointList = ['t', 'r', 'b', 'l', 'lt', 'rt', 'lb', 'rb'];

// 锚点位置
const usePointStyle = (point: string, index: number, attr, cursorResize: string[]) => {
  const { w: width, h: height } = attr;

  const isTop = /t/.test(point);
  const isBottom = /b/.test(point);
  const isLeft = /l/.test(point);
  const isRight = /r/.test(point);

  let newLeft = 0;
  let newTop = 0;

  // 四个角的点
  if (point.length === 2) {
    newLeft = isLeft ? 0 : width;
    newTop = isTop ? 0 : height;
  } else {
    // 上下两点的点，宽度居中
    if (isTop || isBottom) {
      newLeft = width / 2;
      newTop = isTop ? 0 : height;
    }

    // 左右两边的点，高度居中
    if (isLeft || isRight) {
      newLeft = isLeft ? 0 : width;
      newTop = Math.floor(height / 2);
    }
  }

  const style = {
    left: `${newLeft}px`,
    top: `${newTop}px`,
    cursor: cursorResize[index] + '-resize',
  };

  return style;
};

const useMousePointHandle = (e: MouseEvent, point: string, attr) => {
  e.stopPropagation();
  e.preventDefault();

  // 设置拖拽状态

  const itemAttrX = attr.x;
  const itemAttrY = attr.y;
  const itemAttrW = attr.w;
  const itemAttrH = attr.h;

  // 记录点击初始位置
  const startX = e.screenX;
  const startY = e.screenY;

  const mousemove = throttle((moveEvent: MouseEvent) => {
    let currX = Math.round((moveEvent.screenX - startX) / 1);
    let currY = Math.round((moveEvent.screenY - startY) / 1);
    console.log(currX);

    const isTop = /t/.test(point);
    const isBottom = /b/.test(point);
    const isLeft = /l/.test(point);
    const isRight = /r/.test(point);

    const newHeight = itemAttrH + (isTop ? -currY : isBottom ? currY : 0);
    const newWidth = itemAttrW + (isLeft ? -currX : isRight ? currX : 0);

    attr.h = newHeight > 0 ? newHeight : 0;
    attr.w = newWidth > 0 ? newWidth : 0;
    attr.x = itemAttrX + (isLeft ? currX : 0);
    attr.y = itemAttrY + (isTop ? currY : 0);
  }, 50);

  const mouseup = () => {
    document.removeEventListener('mousemove', mousemove);
    document.removeEventListener('mouseup', mouseup);
  };

  document.addEventListener('mousemove', mousemove);
  document.addEventListener('mouseup', mouseup);
};

function handleMouseDownBox(e) {
  e.stopPropagation();
  e.preventDefault();
  const { attr } = item;
  const itemAttrX = attr.x;
  const itemAttrY = attr.y;

  // 记录点击初始位置
  const startX = e.screenX;
  const startY = e.screenY;

  const mousemove = throttle((moveEvent: MouseEvent) => {
    let currX = Math.round((moveEvent.screenX - startX) / 1);
    let currY = Math.round((moveEvent.screenY - startY) / 1);

    attr.x = itemAttrX + currX;
    attr.y = itemAttrY + currY;
  }, 50);

  const mouseup = () => {
    document.removeEventListener('mousemove', mousemove);
    document.removeEventListener('mouseup', mouseup);
  };

  document.addEventListener('mousemove', mousemove);
  document.addEventListener('mouseup', mouseup);
}
</script>

<style lang="scss" scoped>
/* 锚点 */
.shape-point {
  z-index: 1;
  position: absolute;
  width: 7px;
  height: 7px;
  border: 3px solid #000;
  border-radius: 5px;
  background-color: #000;
  transform: translate(-40%, -30%);

  &.t {
    width: 30px;
    transform: translate(-50%, -50%);
  }

  &.b {
    width: 30px;
    transform: translate(-50%, -30%);
  }

  &.l,
  &.r {
    height: 30px;
  }

  &.r {
    transform: translate(-20%, -50%);
  }

  &.l {
    transform: translate(-45%, -50%);
  }

  &.rt,
  &.rb {
    transform: translate(-30%, -30%);
  }
}
</style>
